#include "OurSemanticAnalyzer.h"

#include "main2.h"

/**
 * ToDo lista:
	* - za svaku metodu koja prima SyntaxTreeNode, na pocetku provjeriti da li je primila ispravan node
	* - prijaviti greske koristeci za to predvidjene klase
	* - komentirati; genericki komentari, jer skoro sve metode funkcioniraju na isti nacin; one koje ne, detaljnije objasniti
	* - dodati metode za olaksavanje rada s klasama u kasnijim fazama izrade kompajlera
	* - napisati destruktore
	* - napraviti ostalo sto pise pod // ToDo u samim metodama i ukljucenim klasama
 */




/**
 *  @fn	SemanticNodeClass* OurSemanticAnalyzer::AnalyzeNodeClass(const SyntaxTreeNode *classNode,
 *  	const SemanticNode *parent)
 *
 *  @brief	Performs the analysis of the class node.
 *
 *  @author	Nikola Novak.
 *  @date	6/5/2009.
 *
 *  @param	classNode	The syntax class node.
 *  @param	parent	Semantic node which is a parent to the node which is to be created here.
 *
 *  @return	The generated semantic node class.
 */
SemanticNodeClass *OurSemanticAnalyzer::analyzeNodeClass(const SyntaxTreeNode *classNode, SemanticNode *parent) {
	SemanticNodeClass *snc = new SemanticNodeClass(*classNode, parent);
	SyntaxTreeNode *classBodyNode = classNode->Nodes->GetData(7);
	for (int i = 0; i < classBodyNode->Nodes->GetCount(); ++i) {
		if (classBodyNode->Nodes->GetData(i)->Production == Gr_ClassBody__ClassDefinition) {
			snc->addClass(analyzeNodeClass(classBodyNode->Nodes->GetData(i)->Nodes->GetData(0), snc));
		} else if (classBodyNode->Nodes->GetData(i)->Production == Gr_ClassBody__ConstructorDefinition) {
			snc->addConstructor(new SemanticNodeConstructor(classBodyNode->Nodes->GetData(i)->Nodes->GetData(0), snc));
		} else if (classBodyNode->Nodes->GetData(i)->Production == Gr_ClassBody__EnumDefinition) {
			snc->addEnum(new SemanticNodeEnum(*(classBodyNode->Nodes->GetData(i)->Nodes->GetData(0)), snc));
		} else if (classBodyNode->Nodes->GetData(i)->Production == Gr_ClassBody__FieldDefinition) {
			snc->addFields(SemanticNodeField::analyzeNodeField(classBodyNode->Nodes->GetData(i)->Nodes->GetData(0), snc));
		} else if (classBodyNode->Nodes->GetData(i)->Production == Gr_ClassBody__MethodDefinition) {
			snc->addMethod(new SemanticNodeMethod(classBodyNode->Nodes->GetData(i)->Nodes->GetData(0), snc));
		} else if (classBodyNode->Nodes->GetData(i)->Production == Gr_ClassBody__PropertyDefinition) {
			snc->addProperty(new SemanticNodeProperty(classBodyNode->Nodes->GetData(i)->Nodes->GetData(0), snc));
		} else {
		}
	}
	return snc;
}


/**
=======
>>>>>>> .r45
 *  @fn	SemanticNodeExpression* OurSemanticAnalyzer::analyzeNodeExpression(const SyntaxTreeNode *ex
 *  	pressionNode, const SemanticNode *parent)
 *
 *  @brief	Performs the analysis of the syntax expression node.
 *
 *  @author	Nikola Novak.
 *  @date	6/15/2009.
 *
 *  @param	expressionNode	The node where the expression "begins".
 *  @param	parent	Parent which contains the usings effective in this expression.
 *
 *  @return	Flat semantic expression node.
 */
SemanticNodeExpression *OurSemanticAnalyzer::analyzeNodeExpression(const SyntaxTreeNode *expressionNode, SemanticNode *parent) {
	SemanticNodeExpression *sne = new SemanticNodeExpression(expressionNode, parent);
	// look for first-level value productions
	std::vector<const SyntaxTreeNode *> values = findValueProductions(expressionNode);
	// once found, flatten them and add them to sne
	for (std::vector<const SyntaxTreeNode *>::iterator i = values.begin(); i != values.end(); ++i) {
		if ((*i)->Production == Gr_Value__LITERAL) { /* value */
			sne->addValue(*i);
		} else if ((*i)->Production == Gr_Value__Name_instance_of_Name) { /* is Name(left) an instance of Name(right)? - bool */
			sne->addValue(analyzeNodeInstanceOf(*i, parent), *i);
		} else if ((*i)->Production == Gr_Value__NAME_spLPar_Arguments_spRPar) { /* method call */
			sne->addValue(new SemanticNodeMethodCall(*i, parent), *i);
		} else if ((*i)->Production == Gr_Value__new_DataType_ArrayDefinitionsSize_Initialisation) { /* object array creation */
			sne->addValue(analyzeNodeCreateArray(*i, parent), *i);
		} else if ((*i)->Production == Gr_Value__new_DataType_ArrayDefinitionsSize_spLPar_Arguments_spRPar) { /* object construction */
			sne->addValue(analyzeNodeConstructObject(*i, parent), *i);
		} else if ((*i)->Production == Gr_Value__null) { /* null */
			sne->addValue(*i);
		} else if ((*i)->Production == Gr_Value__spLPar_DataType_spRPar_VariableValue) { /* cast */
			sne->addValue(analyzeNodeCast(*i, parent), *i);
		} else if ((*i)->Production == Gr_Value__spLPar_Expression_spRPar) { /* brackets */
			sne->addValue(analyzeNodeExpression((*i)->Nodes->GetData(1), parent), *i);
		} else if ((*i)->Production == Gr_Value__VariableValue) { /* variable name */
			sne->addValue(analyzeNodeVariableName((*i)->Nodes->GetData(0), parent), *i);
		} else if ((*i)->Production == Gr_Value__VariableValue_spPer_NAME_spLPar_Arguments_spRPar) { /* method call on an instance of a named variable */
			sne->addValue(new SemanticNodeMethodCall(*i, parent), *i);
		} else { /* Cannot happen */ }
	}
	// when done for all value productions, or if there are none, call sne->makeFlat();
	sne->makeFlat();
	return sne;
}
/**
 *  @fn	SemanticNodeInstanceOf* OurSemanticAnalyzer::analyzeNodeInstanceOf(const SyntaxTreeNode *in
 *  	stanceOfNode, const SemanticNode *parent)
 *
 *  @brief	.
 *
 *  @author	Nikola Novak.
 *  @date	6/15/2009.
 *
 *  @param	instanceOfNode	.
 *  @param	parent			.
 *
 *  @return	.
 */
SemanticNodeInstanceOf *OurSemanticAnalyzer::analyzeNodeInstanceOf(const SyntaxTreeNode *instanceOfNode, SemanticNode *parent) {
	return new SemanticNodeInstanceOf(instanceOfNode, parent);
}

/**
 *  @fn	std::vector<SemanticNodeExpression *> OurSemanticAnalyzer::analyzeNodeArgument(const Syntax
 *  	TreeNode *argumentsNode, SemanticNode *parent)
 *
 *  @brief	Analyze node argument.
 *
 *  @author	Nikola Novak
 *  @date	6/19/2009
 *
 *  @param	argumentsNode	If non-null, the arguments node.
 *  @param	parent	If non-null, the parent.
 *
 *  @return	Empty vector if it fails, else vector of expressions (arguments).
 */
std::vector<SemanticNodeExpression *> OurSemanticAnalyzer::analyzeNodeArgument(const SyntaxTreeNode *argumentsNode, SemanticNode *parent) {
	std::vector<SemanticNodeExpression *> res;
	if (argumentsNode->Nodes->GetCount() == 0) return res;
	SyntaxTreeNode *expressionNode = argumentsNode->Nodes->GetData(0);
	res.push_back(analyzeNodeExpression(expressionNode, parent));
	SyntaxTreeNode *additionals = argumentsNode->Nodes->GetData(1);
	for (int x = 0; x < additionals->Nodes->GetCount(); ++x) res.push_back(analyzeNodeExpression(additionals->Nodes->GetData(x)->Nodes->GetData(1), parent));
	return res;
}
/**
 *  @fn	SemanticNodeCreateArray* OurSemanticAnalyzer::analyzeNodeCreateArray(const SyntaxTreeNode *
 *  	createArrayNode, const SemanticNode *parent)
 *
 *  @brief	.
 *
 *  @author	Nikola Novak.
 *  @date	6/15/2009.
 *
 *  @param	createArrayNode	.
 *  @param	parent			.
 *
 *  @return	.
 */
SemanticNodeCreateArray *OurSemanticAnalyzer::analyzeNodeCreateArray(const SyntaxTreeNode *createArrayNode, SemanticNode *parent) {
	SemanticNodeCreateArray *snca = new SemanticNodeCreateArray(createArrayNode, parent);
	std::vector<const SyntaxTreeNode *> dims = snca->getDimensionExpressions();
	std::vector<const SyntaxTreeNode *> inits = snca->getInitializationExpressions();
	for (std::vector<const SyntaxTreeNode *>::iterator i = dims.begin(); i != dims.end(); ++i) snca->addDimension(analyzeNodeExpression(*i, parent));
	for (std::vector<const SyntaxTreeNode *>::iterator i = inits.begin(); i != inits.end(); ++i) snca->addInitializer(analyzeNodeExpression(*i, parent));
	return snca;
}
/**
 *  @fn	SemanticNodeConstructObject* OurSemanticAnalyzer::analyzeNodeConstructObject(const SyntaxTr
 *  	eeNode *constructObjectNode, const SemanticNode *parent)
 *
 *  @brief	.
 *
 *  @author	Nikola Novak.
 *  @date	6/15/2009.
 *
 *  @param	constructObjectNode	.
 *  @param	parent				.
 *
 *  @return	.
 */
SemanticNodeConstructObject *OurSemanticAnalyzer::analyzeNodeConstructObject(const SyntaxTreeNode *constructObjectNode, SemanticNode *parent) {
	SemanticNodeConstructObject *snco = new SemanticNodeConstructObject(constructObjectNode, parent);
	std::vector<const SyntaxTreeNode *> arrExpr = snco->getArrayExpressions();
	for (std::vector<const SyntaxTreeNode *>::iterator i = arrExpr.begin(); i != arrExpr.end(); ++i) {
		snco->addDimension(analyzeNodeExpression(*i, parent));
	}
	if (constructObjectNode->Nodes->GetData(4)->Nodes->GetCount() > 0) snco->addArguments(analyzeNodeArgument(constructObjectNode->Nodes->GetData(4), parent));
	return snco;
}
/**
 *  @fn	SemanticNodeCast* OurSemanticAnalyzer::analyzeNodeCast(const SyntaxTreeNode *castNode,
 *  	const SemanticNode *parent)
 *
 *  @brief	.
 *
 *  @author	Nikola Novak.
 *  @date	6/15/2009.
 *
 *  @param	castNode	.
 *  @param	parent		.
 *
 *  @return	.
 */
SemanticNodeCast *OurSemanticAnalyzer::analyzeNodeCast(const SyntaxTreeNode *castNode, SemanticNode *parent) {
	SemanticNodeCast *snc = new SemanticNodeCast(castNode, parent);
	// ToDo: sintaksno stablo ne gradi se dobro u slucaju kad je cast ispred zagrade: npr. (int)(a / b)
	// ToDo: Hocemo li uopce imat cast?
	// ToDo: obraditi variable value
	return snc;
}
/**
 *  @fn	SemanticNodeVariableName* OurSemanticAnalyzer::analyzeNodeVariableName(const SyntaxTreeNode
 *  	*variableNameNode, const SemanticNode *parent)
 *
 *  @brief	.
 *
 *  @author	Nikola Novak.
 *  @date	6/15/2009.
 *
 *  @param	variableNameNode	.
 *  @param	parent				.
 *
 *  @return	.
 */
SemanticNodeVariableName *OurSemanticAnalyzer::analyzeNodeVariableName(const SyntaxTreeNode *variableNameNode, SemanticNode *parent) {
	SemanticNodeVariableName *snvn = new SemanticNodeVariableName(variableNameNode, parent);
	std::vector<std::vector<const SyntaxTreeNode *> > expNodes = snvn->getExpressions();
	int x = 0, y = 0;
	for (std::vector<std::vector<const SyntaxTreeNode *> >::iterator i = expNodes.begin(); i != expNodes.end(); ++i, ++x) {
		for (std::vector<const SyntaxTreeNode *>::iterator t = (*i).begin(); t != (*i).end(); ++t, ++y) {
			snvn->addExpression(analyzeNodeExpression(*t, parent), x, y);
		}
	}
	return snvn;
}
/**
 *  @fn	std::vector<SyntaxTreeNode*> OurSemanticAnalyzer::findValueProductions(const SyntaxTreeNode
 *  	*expressionNode)
 *
 *  @brief	Finds first-level value production nodes.
 *
 *  @author	Nikola Novak.
 *  @date	6/15/2009.
 *
 *  @param	expressionNode	Expression which contains value nodes.
 *
 *  @return	First-level value production nodes.
 */
std::vector<const SyntaxTreeNode *> OurSemanticAnalyzer::findValueProductions(const SyntaxTreeNode *expressionNode) {
	std::vector<const SyntaxTreeNode *> res;
	for (int x = 0; x < expressionNode->Nodes->GetCount(); ++x) {
		if (isValueNode(expressionNode->Nodes->GetData(x))) {
			res.push_back(expressionNode->Nodes->GetData(x));
		} else {
			std::vector<const SyntaxTreeNode *> childValues = findValueProductions(expressionNode->Nodes->GetData(x));
		 res.insert(res.end(), childValues.begin(), childValues.end());
		}
	}
	return res;
}
/**
 *  @fn	SemanticNodeModel* OurSemanticAnalyzer::analyzeNodeModel(const SyntaxTreeNode *modelNode,
 *  	SemanticNode *parent)
 *
 *  @brief	Analyze node model.
 *
 *  @author	Nikola Novak
 *  @date	6/23/2009
 *
 *  @param	modelNode	If non-null, the model node.
 *  @param	parent		If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeModel *OurSemanticAnalyzer::analyzeNodeModel(const SyntaxTreeNode *modelNode, SemanticNode *parent) {
	SemanticNodeModel *snm = new SemanticNodeModel(modelNode, parent);
	const SyntaxTreeNode *paramNode = modelNode->Nodes->GetData(4);
	snm->addParameters(analyzeNodeParameters(paramNode, snm));
	if (modelNode->Nodes->GetData(9)->Nodes->GetData(1)->Nodes->GetCount() > 0) {
		if (modelNode->Nodes->GetData(9)->Nodes->GetData(1)->Nodes->GetData(2)->Nodes->GetCount() > 0) {
			for (int x = 0; x < modelNode->Nodes->GetData(9)->Nodes->GetData(1)->Nodes->GetData(2)->Nodes->GetCount(); ++x) {
				const SyntaxTreeNode *cNode = modelNode->Nodes->GetData(9)->Nodes->GetData(1)->Nodes->GetData(2)->Nodes->GetData(x);
				if (cNode->Production == Gr_DefineBodyStatement__EnumDefinition) {
					snm->addEnum(new SemanticNodeEnum(*(cNode->Nodes->GetData(0)), snm));
				} else if (cNode->Production == Gr_DefineBodyStatement__FieldDefinition) {
					snm->addFields(SemanticNodeField::analyzeNodeField(cNode->Nodes->GetData(0), snm));
				} else if (cNode->Production == Gr_DefineBodyStatement__MethodDefinition) {
					snm->addMethod(new SemanticNodeMethod(cNode->Nodes->GetData(0), snm));
				} else if (cNode->Production == Gr_DefineBodyStatement__PropertyDefinition) {
					snm->addProperty(new SemanticNodeProperty(cNode->Nodes->GetData(0), snm));
				} else { /* Cannot happen. */ }
			}
		}
	}
	if (modelNode->Nodes->GetData(9)->Nodes->GetData(2)->Nodes->GetCount() > 0) {
		for (int x = 0; x < modelNode->Nodes->GetData(9)->Nodes->GetData(2)->Nodes->GetCount(); ++x) {
			const SyntaxTreeNode *cNode = modelNode->Nodes->GetData(9)->Nodes->GetData(2)->Nodes->GetData(x);
			switch (cNode->Nodes->GetData(1)->Production) {
				case Gr_GpssBlock__AdvanceBlock:
					snm->addBlockAdvance(analyzeNodeBlockAdvance(cNode, snm));
					break;
				case Gr_GpssBlock__ArriveBlock:
					snm->addBlockArrive(analyzeNodeBlockArrive(cNode, snm));
					break;
				case Gr_GpssBlock__CreateBlock:
					snm->addBlockCreate(analyzeNodeBlockCreate(cNode, snm));
					break;
				case Gr_GpssBlock__DepartBlock:
					snm->addBlockDepart(analyzeNodeBlockDepart(cNode, snm));
					break;
				case Gr_GpssBlock__EnterBlock:
					snm->addBlockEnter(analyzeNodeBlockEnter(cNode, snm));
					break;
				case Gr_GpssBlock__ExecuteBlock:
					snm->addBlockExecute(analyzeNodeBlockExecute(cNode, snm));
					break;
				case Gr_GpssBlock__GatherBlock:
					snm->addBlockGather(analyzeNodeBlockGather(cNode, snm));
					break;
				case Gr_GpssBlock__GenerateBlock:
					snm->addBlockGenerate(analyzeNodeBlockGenerate(cNode, snm));
					break;
				case Gr_GpssBlock__GotoBlock:
					snm->addBlockGoto(analyzeNodeBlockGoto(cNode, snm));
					break;
				case Gr_GpssBlock__IfBlock:
					snm->addBlockIf(analyzeNodeBlockIf(cNode, snm));
					break;
				case Gr_GpssBlock__InqueueBlock:
					snm->addBlockInqueue(analyzeNodeBlockInqueue(cNode, snm));
					break;
				case Gr_GpssBlock__JoinGroupBlock:
					snm->addBlockJoinGroup(analyzeNodeBlockJoinGroup(cNode, snm));
					break;
				case Gr_GpssBlock__LeaveBlock:
					snm->addBlockLeave(analyzeNodeBlockLeave(cNode, snm));
					break;
				case Gr_GpssBlock__LeaveGroupBlock:
					snm->addBlockLeaveGroup(analyzeNodeBlockLeaveGroup(cNode, snm));
					break;
				case Gr_GpssBlock__ModelInstanceBlock:
					snm->addBlockModelInstance(analyzeNodeBlockModelInstance(cNode, snm));
					break;
				case Gr_GpssBlock__OutqueueBlock:
					snm->addBlockOutqueue(analyzeNodeBlockOutqueue(cNode, snm));
					break;
				case Gr_GpssBlock__ReleaseBlock:
					snm->addBlockRelease(analyzeNodeBlockRelease(cNode, snm));
					break;
				case Gr_GpssBlock__SeizeBlock:
					snm->addBlockSeize(analyzeNodeBlockSeize(cNode, snm));
					break;
				case Gr_GpssBlock__SplitBlock:
					snm->addBlockSplit(analyzeNodeBlockSplit(cNode, snm));
					break;
				case Gr_GpssBlock__TerminateBlock:
					snm->addBlockTerminate(analyzeNodeBlockTerminate(cNode, snm));
					break;
				case Gr_GpssBlock__WaitBlock:
					snm->addBlockWait(analyzeNodeBlockWait(cNode, snm));
					break;
				default: break;
			}
		}
	}
	return snm;
}
/**
 *  @fn	std::vector<SemanticNodeField*> OurSemanticAnalyzer::analyzeNodeParameters(const SyntaxTree
 *  	Node *parametersNode, SemanticNode *parent)
 *
 *  @brief	Analyze node parameters.
 *
 *  @author	Nikola Novak
 *  @date	6/23/2009
 *
 *  @param	parametersNode	If non-null, the parameters node.
 *  @param	parent			If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
std::vector<SemanticNodeField *> OurSemanticAnalyzer::analyzeNodeParameters(const SyntaxTreeNode *parametersNode, SemanticNode *parent) {
	std::vector<SemanticNodeField *> result;
	if (parametersNode->Nodes->GetCount() > 0) {
		SyntaxTreeNode *type = parametersNode->Nodes->GetData(0)->Nodes->GetData(0);
		SyntaxTreeNode *name = new SyntaxTreeNode();
		SyntaxTreeNode *name2 = new SyntaxTreeNode();
		name->Nodes->Add(name2);
		name2->Nodes->Add(parametersNode->Nodes->GetData(0)->Nodes->GetData(1));
		name2->Nodes->Add(parametersNode->Nodes->GetData(0)->Nodes->GetData(2));
		SemanticNodeField *snf = new SemanticNodeField(NULL, type, name, parent);
		result.push_back(snf);
		for (int x = 0; x < parametersNode->Nodes->GetData(1)->Nodes->GetCount(); ++x) {
			const SyntaxTreeNode *cNode = parametersNode->Nodes->GetData(1)->Nodes->GetData(x);
			type = cNode->Nodes->GetData(1)->Nodes->GetData(0);
			name2->Nodes->RemoveAtWithoutFreeMem(1);
			name2->Nodes->RemoveAtWithoutFreeMem(0);
			name2->Nodes->Add(cNode->Nodes->GetData(1)->Nodes->GetData(1));
			name2->Nodes->Add(cNode->Nodes->GetData(1)->Nodes->GetData(2));
			snf = new SemanticNodeField(NULL, type, name, parent);
			result.push_back(snf);
		}
		name2->Nodes->RemoveAtWithoutFreeMem(1);
		name2->Nodes->RemoveAtWithoutFreeMem(0);
		delete name;
	}
	return result;
}
/**
 *  @fn	SemanticNodeBlockTerminate* OurSemanticAnalyzer::analyzeNodeBlockTerminate(const SyntaxTree
 *  	Node *terminateNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block terminate.
 *
 *  @author	Nikola Novak
 *  @date	6/23/2009
 *
 *  @param	terminateNodeParent	If non-null, the terminate node parent.
 *  @param	parent				If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockTerminate *OurSemanticAnalyzer::analyzeNodeBlockTerminate(const SyntaxTreeNode *terminateNodeParent, SemanticNode *parent) {
 SemanticNodeBlockTerminate *snbt = new SemanticNodeBlockTerminate(terminateNodeParent, parent);
	if (terminateNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Production == Gr_TerminateBlock__terminate_Expression_spSemiCol) {
	 snbt->setExpression(analyzeNodeExpression(terminateNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(1), parent));
	}
	return snbt;
}
/**
 *  @fn	SemanticNodeBlockGenerate* OurSemanticAnalyzer::analyzeNodeBlockGenerate(const SyntaxTreeNo
 *  	de *generateNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block generate.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	generateNodeParent	If non-null, the generate node parent.
 *  @param	parent				If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockGenerate *OurSemanticAnalyzer::analyzeNodeBlockGenerate(const SyntaxTreeNode *generateNodeParent, SemanticNode *parent) {
	SemanticNodeBlockGenerate *snbg = new SemanticNodeBlockGenerate(generateNodeParent, parent);
	const SyntaxTreeNode *reqNode = generateNodeParent->Nodes->GetData(1)->Nodes->GetData(0);
	if (snbg->hasAfter()) snbg->setAfterExpression(analyzeNodeExpression(reqNode->Nodes->GetData(3)->Nodes->GetData(1), parent));
	if (snbg->hasDeviation()) snbg->setDeviationExpression(analyzeNodeExpression(reqNode->Nodes->GetData(4)->Nodes->GetData(2)->Nodes->GetData(1), parent));
	if (snbg->hasEvery()) snbg->setEveryExpression(analyzeNodeExpression(reqNode->Nodes->GetData(4)->Nodes->GetData(1), parent));
	if (snbg->hasUpto()) snbg->setUptoExpression(analyzeNodeExpression(reqNode->Nodes->GetData(1)->Nodes->GetData(1), parent));
	if (snbg->hasTransactionList()) {
		const SyntaxTreeNode *transListNode = reqNode->Nodes->GetData(2)->Nodes->GetData(2);
		SyntaxTreeNode *name = transListNode->Nodes->GetData(0);
		SyntaxTreeNode *expression = transListNode->Nodes->GetData(2);
		snbg->addTransaction(flattenNamePeriodAdd(*name), analyzeNodeExpression(expression, parent));
		SyntaxTreeNode *nextListNode = transListNode->Nodes->GetData(3);
		for (int x = 0; x < nextListNode->Nodes->GetCount(); ++x) {
			name = nextListNode->Nodes->GetData(x)->Nodes->GetData(1);
			expression = nextListNode->Nodes->GetData(x)->Nodes->GetData(3);
		}
	}
	return snbg;
}
/**
 *  @fn	SemanticNodeBlockAdvance* OurSemanticAnalyzer::analyzeNodeBlockAdvance(const SyntaxTreeNode
 *  	*advanceNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block advance.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	advanceNodeParent	If non-null, the advance node parent.
 *  @param	parent				If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockAdvance *OurSemanticAnalyzer::analyzeNodeBlockAdvance(const SyntaxTreeNode *advanceNodeParent, SemanticNode *parent) {
	SemanticNodeBlockAdvance *snba = new SemanticNodeBlockAdvance(advanceNodeParent, parent);
	snba->setTime(analyzeNodeExpression(advanceNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(1), parent));
	if (snba->hasDeviation()) snba->setDeviation(analyzeNodeExpression(advanceNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(2)->Nodes->GetData(1), parent));
	return snba;
}
/**
 *  @fn	SemanticNodeBlockEnter* OurSemanticAnalyzer::analyzeNodeBlockEnter(const SyntaxTreeNode *en
 *  	terNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block enter.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	enterNodeParent	If non-null, the enter node parent.
 *  @param	parent			If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockEnter *OurSemanticAnalyzer::analyzeNodeBlockEnter(const SyntaxTreeNode *enterNodeParent, SemanticNode *parent) {
	SemanticNodeBlockEnter *snbe = new SemanticNodeBlockEnter(enterNodeParent, parent);
	snbe->setStorage(analyzeNodeExpression(enterNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(2), parent));
	if (snbe->hasQueue()) snbe->setQueue(analyzeNodeExpression(enterNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(3)->Nodes->GetData(1), parent));
	if (snbe->hasUnitNumber()) snbe->setUnitNumber(analyzeNodeExpression(enterNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(1)->Nodes->GetData(0), parent));
	return snbe;
}
/**
 *  @fn	SemanticNodeBlockLeave* OurSemanticAnalyzer::analyzeNodeBlockLeave(const SyntaxTreeNode *le
 *  	aveNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block leave.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	leaveNodeParent	If non-null, the leave node parent.
 *  @param	parent			If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockLeave *OurSemanticAnalyzer::analyzeNodeBlockLeave(const SyntaxTreeNode *leaveNodeParent, SemanticNode *parent) {
	SemanticNodeBlockLeave *snbl = new SemanticNodeBlockLeave(leaveNodeParent, parent);
	snbl->setStorage(analyzeNodeExpression(leaveNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(2), parent));
	if (snbl->hasUnitsFrom()) snbl->setUnitsFrom(analyzeNodeExpression(leaveNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(1)->Nodes->GetData(0), parent));
	return snbl;
}
/**
 *  @fn	SemanticNodeBlockSeize* OurSemanticAnalyzer::analyzeNodeBlockSeize(const SyntaxTreeNode *se
 *  	izeNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block seize.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	seizeNodeParent	If non-null, the seize node parent.
 *  @param	parent			If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockSeize *OurSemanticAnalyzer::analyzeNodeBlockSeize(const SyntaxTreeNode *seizeNodeParent, SemanticNode *parent) {
	SemanticNodeBlockSeize *snbs = new SemanticNodeBlockSeize(seizeNodeParent, parent);
	snbs->setFacility(analyzeNodeExpression(seizeNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(1), parent));
	if (snbs->hasQueue()) snbs->setQueue(analyzeNodeExpression(seizeNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(2)->Nodes->GetData(1), parent));
	return snbs;
}
/**
 *  @fn	SemanticNodeBlockRelease* OurSemanticAnalyzer::analyzeNodeBlockRelease(const SyntaxTreeNode
 *  	*releaseNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block release.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	releaseNodeParent	If non-null, the release node parent.
 *  @param	parent				If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockRelease *OurSemanticAnalyzer::analyzeNodeBlockRelease(const SyntaxTreeNode *releaseNodeParent, SemanticNode *parent) {
	SemanticNodeBlockRelease *snbr = new SemanticNodeBlockRelease(releaseNodeParent, parent);
	snbr->setRelease(analyzeNodeExpression(releaseNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(1), parent));
	return snbr;
}
/**
 *  @fn	SemanticNodeBlockInqueue* OurSemanticAnalyzer::analyzeNodeBlockInqueue(const SyntaxTreeNode
 *  	*inqueueNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block inqueue.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	inqueueNodeParent	If non-null, the inqueue node parent.
 *  @param	parent				If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockInqueue *OurSemanticAnalyzer::analyzeNodeBlockInqueue(const SyntaxTreeNode *inqueueNodeParent, SemanticNode *parent) {
	SemanticNodeBlockInqueue *snbi = new SemanticNodeBlockInqueue(inqueueNodeParent, parent);
	snbi->setQueue(analyzeNodeExpression(inqueueNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(1), parent));
	return snbi;
}
/**
 *  @fn	SemanticNodeBlockOutqueue* OurSemanticAnalyzer::analyzeNodeBlockOutqueue(const SyntaxTreeNo
 *  	de *outqueueNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block outqueue.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	outqueueNodeParent	If non-null, the outqueue node parent.
 *  @param	parent				If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockOutqueue *OurSemanticAnalyzer::analyzeNodeBlockOutqueue(const SyntaxTreeNode *outqueueNodeParent, SemanticNode *parent) {
	SemanticNodeBlockOutqueue *snbo = new SemanticNodeBlockOutqueue(outqueueNodeParent, parent);
	snbo->setQueue(analyzeNodeExpression(outqueueNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(1), parent));
	return snbo;
}
/**
 *  @fn	SemanticNodeBlockArrive* OurSemanticAnalyzer::analyzeNodeBlockArrive(const SyntaxTreeNode *
 *  	arriveNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block arrive.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	arriveNodeParent	If non-null, the arrive node parent.
 *  @param	parent				If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockArrive *OurSemanticAnalyzer::analyzeNodeBlockArrive(const SyntaxTreeNode *arriveNodeParent, SemanticNode *parent) {
	SemanticNodeBlockArrive *snba = new SemanticNodeBlockArrive(arriveNodeParent, parent);
	snba->setADTable(analyzeNodeExpression(arriveNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(1), parent));
	return snba;
}
/**
 *  @fn	SemanticNodeBlockDepart* OurSemanticAnalyzer::analyzeNodeBlockDepart(const SyntaxTreeNode *
 *  	departNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block depart.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	departNodeParent	If non-null, the depart node parent.
 *  @param	parent				If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockDepart *OurSemanticAnalyzer::analyzeNodeBlockDepart(const SyntaxTreeNode *departNodeParent, SemanticNode *parent) {
	SemanticNodeBlockDepart *snbd = new SemanticNodeBlockDepart(departNodeParent, parent);
	snbd->setADTable(analyzeNodeExpression(departNodeParent->Nodes->GetData(1)->Nodes->GetData(0)->Nodes->GetData(1), parent));
	return snbd;
}
/**
 *  @fn	SemanticNodeBlockModelInstance* OurSemanticAnalyzer::analyzeNodeBlockModelInstance(const Sy
 *  	ntaxTreeNode *modelInstanceNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block model instance.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	modelInstanceNodeParent	If non-null, the model instance node parent.
 *  @param	parent					If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockModelInstance *OurSemanticAnalyzer::analyzeNodeBlockModelInstance(const SyntaxTreeNode *modelInstanceNodeParent, SemanticNode *parent) {
	SemanticNodeBlockModelInstance *snbmi = new SemanticNodeBlockModelInstance(modelInstanceNodeParent, parent);
	const SyntaxTreeNode *theNode = modelInstanceNodeParent->Nodes->GetData(1)->Nodes->GetData(0);
	bool full = (theNode->Production == Gr_ModelInstanceBlock__model_Name_spLPar_Arguments_spRPar_spSemiCol);
	if (full) snbmi->addParameters(analyzeNodeArgument(theNode->Nodes->GetData(3), parent));
	else snbmi->addParameters(analyzeNodeArgument(theNode->Nodes->GetData(2), parent));
	return snbmi;
}
/**
 *  @fn	SemanticNodeBlockGoto* OurSemanticAnalyzer::analyzeNodeBlockGoto(const SyntaxTreeNode *goto
 *  	NodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block goto.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	gotoNodeParent	If non-null, the goto node parent.
 *  @param	parent			If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockGoto *OurSemanticAnalyzer::analyzeNodeBlockGoto(const SyntaxTreeNode *gotoNodeParent, SemanticNode *parent) {
	SemanticNodeBlockGoto *snbg = new SemanticNodeBlockGoto(gotoNodeParent, parent);
	const SyntaxTreeNode *theNode = gotoNodeParent->Nodes->GetData(1)->Nodes->GetData(0);
	return snbg;
}
/**
 *  @fn	SemanticNodeBlockIf* OurSemanticAnalyzer::analyzeNodeBlockIf(const SyntaxTreeNode *ifNodePa
 *  	rent, SemanticNode *parent)
 *
 *  @brief	Analyze node block if.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	ifNodeParent	If non-null, if node parent.
 *  @param	parent			If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockIf *OurSemanticAnalyzer::analyzeNodeBlockIf(const SyntaxTreeNode *ifNodeParent, SemanticNode *parent) {
	SemanticNodeBlockIf *snbi = new SemanticNodeBlockIf(ifNodeParent, parent);
	const SyntaxTreeNode *theNode = ifNodeParent->Nodes->GetData(1)->Nodes->GetData(0);
	snbi->setExpression(analyzeNodeExpression(theNode->Nodes->GetData(2), parent));
	for (int x = 0; x < theNode->Nodes->GetData(5)->Nodes->GetCount(); ++x) {
		const SyntaxTreeNode *theOtherNode = theNode->Nodes->GetData(5)->Nodes->GetData(x);
		switch (theOtherNode->Nodes->GetData(1)->Production) {
			case Gr_GpssBlock__AdvanceBlock:
				snbi->addBlockAdvance(analyzeNodeBlockAdvance(theOtherNode, parent));
				break;
			case Gr_GpssBlock__ArriveBlock:
				snbi->addBlockArrive(analyzeNodeBlockArrive(theOtherNode, parent));
				break;
			case Gr_GpssBlock__CreateBlock:
				snbi->addBlockCreate(analyzeNodeBlockCreate(theOtherNode, parent));
				break;
			case Gr_GpssBlock__DepartBlock:
				snbi->addBlockDepart(analyzeNodeBlockDepart(theOtherNode, parent));
				break;
			case Gr_GpssBlock__EnterBlock:
				snbi->addBlockEnter(analyzeNodeBlockEnter(theOtherNode, parent));
				break;
			case Gr_GpssBlock__ExecuteBlock:
				snbi->addBlockExecute(analyzeNodeBlockExecute(theOtherNode, parent));
				break;
			case Gr_GpssBlock__GatherBlock:
				snbi->addBlockGather(analyzeNodeBlockGather(theOtherNode, parent));
				break;
			case Gr_GpssBlock__GenerateBlock:
				snbi->addBlockGenerate(analyzeNodeBlockGenerate(theOtherNode, parent));
				break;
			case Gr_GpssBlock__GotoBlock:
				snbi->addBlockGoto(analyzeNodeBlockGoto(theOtherNode, parent));
				break;
			case Gr_GpssBlock__IfBlock:
				snbi->addBlockIf(analyzeNodeBlockIf(theOtherNode, parent));
				break;
			case Gr_GpssBlock__InqueueBlock:
				snbi->addBlockInqueue(analyzeNodeBlockInqueue(theOtherNode, parent));
				break;
			case Gr_GpssBlock__JoinGroupBlock:
				snbi->addBlockJoinGroup(analyzeNodeBlockJoinGroup(theOtherNode, parent));
				break;
			case Gr_GpssBlock__LeaveBlock:
				snbi->addBlockLeave(analyzeNodeBlockLeave(theOtherNode, parent));
				break;
			case Gr_GpssBlock__LeaveGroupBlock:
				snbi->addBlockLeaveGroup(analyzeNodeBlockLeaveGroup(theOtherNode, parent));
				break;
			case Gr_GpssBlock__ModelInstanceBlock:
				snbi->addBlockModelInstance(analyzeNodeBlockModelInstance(theOtherNode, parent));
				break;
			case Gr_GpssBlock__OutqueueBlock:
				snbi->addBlockOutqueue(analyzeNodeBlockOutqueue(theOtherNode, parent));
				break;
			case Gr_GpssBlock__ReleaseBlock:
				snbi->addBlockRelease(analyzeNodeBlockRelease(theOtherNode, parent));
				break;
			case Gr_GpssBlock__SeizeBlock:
				snbi->addBlockSeize(analyzeNodeBlockSeize(theOtherNode, parent));
				break;
			case Gr_GpssBlock__SplitBlock:
				snbi->addBlockSplit(analyzeNodeBlockSplit(theOtherNode, parent));
				break;
			case Gr_GpssBlock__TerminateBlock:
				snbi->addBlockTerminate(analyzeNodeBlockTerminate(theOtherNode, parent));
				break;
			case Gr_GpssBlock__WaitBlock:
				snbi->addBlockWait(analyzeNodeBlockWait(theOtherNode, parent));
				break;
			default: break;
		}
	}
	if (snbi->hasElse()) {
	 for (int x = 0; x < theNode->Nodes->GetData(7)->Nodes->GetData(2)->Nodes->GetCount(); ++x) {
	 	const SyntaxTreeNode *theOtherNode = theNode->Nodes->GetData(7)->Nodes->GetData(2)->Nodes->GetData(x);
	 	switch (theOtherNode->Nodes->GetData(1)->Production) {
	 		case Gr_GpssBlock__AdvanceBlock:
	 			snbi->addBlockAdvance(analyzeNodeBlockAdvance(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__ArriveBlock:
	 			snbi->addBlockArrive(analyzeNodeBlockArrive(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__CreateBlock:
	 			snbi->addBlockCreate(analyzeNodeBlockCreate(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__DepartBlock:
	 			snbi->addBlockDepart(analyzeNodeBlockDepart(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__EnterBlock:
	 			snbi->addBlockEnter(analyzeNodeBlockEnter(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__ExecuteBlock:
	 			snbi->addBlockExecute(analyzeNodeBlockExecute(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__GatherBlock:
	 			snbi->addBlockGather(analyzeNodeBlockGather(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__GenerateBlock:
	 			snbi->addBlockGenerate(analyzeNodeBlockGenerate(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__GotoBlock:
	 			snbi->addBlockGoto(analyzeNodeBlockGoto(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__IfBlock:
	 			snbi->addBlockIf(analyzeNodeBlockIf(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__InqueueBlock:
	 			snbi->addBlockInqueue(analyzeNodeBlockInqueue(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__JoinGroupBlock:
	 			snbi->addBlockJoinGroup(analyzeNodeBlockJoinGroup(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__LeaveBlock:
	 			snbi->addBlockLeave(analyzeNodeBlockLeave(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__LeaveGroupBlock:
	 			snbi->addBlockLeaveGroup(analyzeNodeBlockLeaveGroup(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__ModelInstanceBlock:
	 			snbi->addBlockModelInstance(analyzeNodeBlockModelInstance(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__OutqueueBlock:
	 			snbi->addBlockOutqueue(analyzeNodeBlockOutqueue(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__ReleaseBlock:
	 			snbi->addBlockRelease(analyzeNodeBlockRelease(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__SeizeBlock:
	 			snbi->addBlockSeize(analyzeNodeBlockSeize(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__SplitBlock:
	 			snbi->addBlockSplit(analyzeNodeBlockSplit(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__TerminateBlock:
	 			snbi->addBlockTerminate(analyzeNodeBlockTerminate(theOtherNode, parent), true);
	 			break;
	 		case Gr_GpssBlock__WaitBlock:
	 			snbi->addBlockWait(analyzeNodeBlockWait(theOtherNode, parent), true);
	 			break;
	 		default: break;
	 	}
	 }
	}
	return snbi;
}
/**
 *  @fn	SemanticNodeBlockWait* OurSemanticAnalyzer::analyzeNodeBlockWait(const SyntaxTreeNode *wait
 *  	NodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block wait.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	waitNodeParent	If non-null, the wait node parent.
 *  @param	parent			If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockWait *OurSemanticAnalyzer::analyzeNodeBlockWait(const SyntaxTreeNode *waitNodeParent, SemanticNode *parent) {
	SemanticNodeBlockWait *smbw = new SemanticNodeBlockWait(waitNodeParent, parent);
	const SyntaxTreeNode *theNode = waitNodeParent->Nodes->GetData(1)->Nodes->GetData(0);
	if (smbw->hasSensitivityList()) {
		const SyntaxTreeNode *firstItem = theNode->Nodes->GetData(1)->Nodes->GetData(1);
		smbw->addSensitivityName(flattenNamePeriodAdd(*firstItem->Nodes->GetData(0)));
		SyntaxTreeNode *moreItems = firstItem->Nodes->GetData(1);
		for (int x = 0; x < moreItems->Nodes->GetCount(); ++x) {
			smbw->addSensitivityName(flattenNamePeriodAdd(*moreItems->Nodes->GetData(x)->Nodes->GetData(1)));
		}
	}
	if (smbw->hasExplicitQueue()) smbw->setQueue(analyzeNodeExpression(theNode->Nodes->GetData(2)->Nodes->GetData(1), parent));
	smbw->setCondition(analyzeNodeExpression(theNode->Nodes->GetData(5), parent));
	if (smbw->hasThenStructure()) {
		const SyntaxTreeNode *msNode = theNode->Nodes->GetData(7)->Nodes->GetData(2);
		for (int x = 0; x < msNode->Nodes->GetCount(); ++x) {
			const SyntaxTreeNode *cNode = msNode->Nodes->GetData(x);
			switch (cNode->Nodes->GetData(1)->Production) {
				case Gr_GpssBlock__AdvanceBlock:
					smbw->addBlockAdvance(analyzeNodeBlockAdvance(cNode, smbw));
					break;
				case Gr_GpssBlock__ArriveBlock:
					smbw->addBlockArrive(analyzeNodeBlockArrive(cNode, smbw));
					break;
				case Gr_GpssBlock__CreateBlock:
					smbw->addBlockCreate(analyzeNodeBlockCreate(cNode, smbw));
					break;
				case Gr_GpssBlock__DepartBlock:
					smbw->addBlockDepart(analyzeNodeBlockDepart(cNode, smbw));
					break;
				case Gr_GpssBlock__EnterBlock:
					smbw->addBlockEnter(analyzeNodeBlockEnter(cNode, smbw));
					break;
				case Gr_GpssBlock__ExecuteBlock:
					smbw->addBlockExecute(analyzeNodeBlockExecute(cNode, smbw));
					break;
				case Gr_GpssBlock__GatherBlock:
					smbw->addBlockGather(analyzeNodeBlockGather(cNode, smbw));
					break;
				case Gr_GpssBlock__GenerateBlock:
					smbw->addBlockGenerate(analyzeNodeBlockGenerate(cNode, smbw));
					break;
				case Gr_GpssBlock__GotoBlock:
					smbw->addBlockGoto(analyzeNodeBlockGoto(cNode, smbw));
					break;
				case Gr_GpssBlock__IfBlock:
					smbw->addBlockIf(analyzeNodeBlockIf(cNode, smbw));
					break;
				case Gr_GpssBlock__InqueueBlock:
					smbw->addBlockInqueue(analyzeNodeBlockInqueue(cNode, smbw));
					break;
				case Gr_GpssBlock__JoinGroupBlock:
					smbw->addBlockJoinGroup(analyzeNodeBlockJoinGroup(cNode, smbw));
					break;
				case Gr_GpssBlock__LeaveBlock:
					smbw->addBlockLeave(analyzeNodeBlockLeave(cNode, smbw));
					break;
				case Gr_GpssBlock__LeaveGroupBlock:
					smbw->addBlockLeaveGroup(analyzeNodeBlockLeaveGroup(cNode, smbw));
					break;
				case Gr_GpssBlock__ModelInstanceBlock:
					smbw->addBlockModelInstance(analyzeNodeBlockModelInstance(cNode, smbw));
					break;
				case Gr_GpssBlock__OutqueueBlock:
					smbw->addBlockOutqueue(analyzeNodeBlockOutqueue(cNode, smbw));
					break;
				case Gr_GpssBlock__ReleaseBlock:
					smbw->addBlockRelease(analyzeNodeBlockRelease(cNode, smbw));
					break;
				case Gr_GpssBlock__SeizeBlock:
					smbw->addBlockSeize(analyzeNodeBlockSeize(cNode, smbw));
					break;
				case Gr_GpssBlock__SplitBlock:
					smbw->addBlockSplit(analyzeNodeBlockSplit(cNode, smbw));
					break;
				case Gr_GpssBlock__TerminateBlock:
					smbw->addBlockTerminate(analyzeNodeBlockTerminate(cNode, smbw));
					break;
				case Gr_GpssBlock__WaitBlock:
					smbw->addBlockWait(analyzeNodeBlockWait(cNode, smbw));
					break;
				default: break;
			}
		}
	}
	if (smbw->hasElseStructure()) {
		const SyntaxTreeNode *msNode = theNode->Nodes->GetData(8)->Nodes->GetData(2);
		for (int x = 0; x < msNode->Nodes->GetCount(); ++x) {
			const SyntaxTreeNode *cNode = msNode->Nodes->GetData(x);
			switch (cNode->Nodes->GetData(1)->Production) {
				case Gr_GpssBlock__AdvanceBlock:
					smbw->addBlockAdvance(analyzeNodeBlockAdvance(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__ArriveBlock:
					smbw->addBlockArrive(analyzeNodeBlockArrive(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__CreateBlock:
					smbw->addBlockCreate(analyzeNodeBlockCreate(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__DepartBlock:
					smbw->addBlockDepart(analyzeNodeBlockDepart(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__EnterBlock:
					smbw->addBlockEnter(analyzeNodeBlockEnter(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__ExecuteBlock:
					smbw->addBlockExecute(analyzeNodeBlockExecute(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__GatherBlock:
					smbw->addBlockGather(analyzeNodeBlockGather(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__GenerateBlock:
					smbw->addBlockGenerate(analyzeNodeBlockGenerate(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__GotoBlock:
					smbw->addBlockGoto(analyzeNodeBlockGoto(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__IfBlock:
					smbw->addBlockIf(analyzeNodeBlockIf(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__InqueueBlock:
					smbw->addBlockInqueue(analyzeNodeBlockInqueue(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__JoinGroupBlock:
					smbw->addBlockJoinGroup(analyzeNodeBlockJoinGroup(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__LeaveBlock:
					smbw->addBlockLeave(analyzeNodeBlockLeave(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__LeaveGroupBlock:
					smbw->addBlockLeaveGroup(analyzeNodeBlockLeaveGroup(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__ModelInstanceBlock:
					smbw->addBlockModelInstance(analyzeNodeBlockModelInstance(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__OutqueueBlock:
					smbw->addBlockOutqueue(analyzeNodeBlockOutqueue(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__ReleaseBlock:
					smbw->addBlockRelease(analyzeNodeBlockRelease(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__SeizeBlock:
					smbw->addBlockSeize(analyzeNodeBlockSeize(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__SplitBlock:
					smbw->addBlockSplit(analyzeNodeBlockSplit(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__TerminateBlock:
					smbw->addBlockTerminate(analyzeNodeBlockTerminate(cNode, smbw), 1);
					break;
				case Gr_GpssBlock__WaitBlock:
					smbw->addBlockWait(analyzeNodeBlockWait(cNode, smbw), 1);
					break;
				default: break;
			}
		}
	}
	if (smbw->hasTimeout()) {
		smbw->setTimeout(analyzeNodeExpression(theNode->Nodes->GetData(9)->Nodes->GetData(1), parent));
		if (smbw->hasTimeoutBlock()) {
		 const SyntaxTreeNode *msNode = theNode->Nodes->GetData(9)->Nodes->GetData(3);
		 for (int x = 0; x < msNode->Nodes->GetCount(); ++x) {
		 	const SyntaxTreeNode *cNode = msNode->Nodes->GetData(x);
		 	switch (cNode->Nodes->GetData(1)->Production) {
		 		case Gr_GpssBlock__AdvanceBlock:
		 			smbw->addBlockAdvance(analyzeNodeBlockAdvance(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__ArriveBlock:
		 			smbw->addBlockArrive(analyzeNodeBlockArrive(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__CreateBlock:
		 			smbw->addBlockCreate(analyzeNodeBlockCreate(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__DepartBlock:
		 			smbw->addBlockDepart(analyzeNodeBlockDepart(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__EnterBlock:
		 			smbw->addBlockEnter(analyzeNodeBlockEnter(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__ExecuteBlock:
		 			smbw->addBlockExecute(analyzeNodeBlockExecute(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__GatherBlock:
		 			smbw->addBlockGather(analyzeNodeBlockGather(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__GenerateBlock:
		 			smbw->addBlockGenerate(analyzeNodeBlockGenerate(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__GotoBlock:
		 			smbw->addBlockGoto(analyzeNodeBlockGoto(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__IfBlock:
		 			smbw->addBlockIf(analyzeNodeBlockIf(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__InqueueBlock:
		 			smbw->addBlockInqueue(analyzeNodeBlockInqueue(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__JoinGroupBlock:
		 			smbw->addBlockJoinGroup(analyzeNodeBlockJoinGroup(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__LeaveBlock:
		 			smbw->addBlockLeave(analyzeNodeBlockLeave(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__LeaveGroupBlock:
		 			smbw->addBlockLeaveGroup(analyzeNodeBlockLeaveGroup(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__ModelInstanceBlock:
		 			smbw->addBlockModelInstance(analyzeNodeBlockModelInstance(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__OutqueueBlock:
		 			smbw->addBlockOutqueue(analyzeNodeBlockOutqueue(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__ReleaseBlock:
		 			smbw->addBlockRelease(analyzeNodeBlockRelease(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__SeizeBlock:
		 			smbw->addBlockSeize(analyzeNodeBlockSeize(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__SplitBlock:
		 			smbw->addBlockSplit(analyzeNodeBlockSplit(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__TerminateBlock:
		 			smbw->addBlockTerminate(analyzeNodeBlockTerminate(cNode, smbw), 2);
		 			break;
		 		case Gr_GpssBlock__WaitBlock:
		 			smbw->addBlockWait(analyzeNodeBlockWait(cNode, smbw), 2);
		 			break;
		 		default: break;
		 	}
		 }
		}
	}
	return smbw;
}
/**
 *  @fn	SemanticNodeBlockJoinGroup* OurSemanticAnalyzer::analyzeNodeBlockJoinGroup(const SyntaxTree
 *  	Node *joinGroupNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block join group.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	joinGroupNodeParent	If non-null, the join group node parent.
 *  @param	parent				If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockJoinGroup *OurSemanticAnalyzer::analyzeNodeBlockJoinGroup(const SyntaxTreeNode *joinGroupNodeParent, SemanticNode *parent) {
	SemanticNodeBlockJoinGroup *snbjg = new SemanticNodeBlockJoinGroup(joinGroupNodeParent, parent);
	const SyntaxTreeNode *theNode = joinGroupNodeParent->Nodes->GetData(1)->Nodes->GetData(0);
	snbjg->setGroup(analyzeNodeExpression(theNode->Nodes->GetData(2), parent));
	return snbjg;
}
/**
 *  @fn	SemanticNodeBlockLeaveGroup* OurSemanticAnalyzer::analyzeNodeBlockLeaveGroup(const SyntaxTr
 *  	eeNode *leaveGroupNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block leave group.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	leaveGroupNodeParent	If non-null, the leave group node parent.
 *  @param	parent					If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockLeaveGroup *OurSemanticAnalyzer::analyzeNodeBlockLeaveGroup(const SyntaxTreeNode *leaveGroupNodeParent, SemanticNode *parent) {
	SemanticNodeBlockLeaveGroup *snblg = new SemanticNodeBlockLeaveGroup(leaveGroupNodeParent, parent);
	const SyntaxTreeNode *theNode = leaveGroupNodeParent->Nodes->GetData(1)->Nodes->GetData(0);
	snblg->setGroup(analyzeNodeExpression(theNode->Nodes->GetData(2), parent));
	return snblg;
}
/**
 *  @fn	SemanticNodeBlockCreate* OurSemanticAnalyzer::analyzeNodeBlockCreate(const SyntaxTreeNode *
 *  	createNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block create.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	createNodeParent	If non-null, the create node parent.
 *  @param	parent				If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockCreate *OurSemanticAnalyzer::analyzeNodeBlockCreate(const SyntaxTreeNode *createNodeParent, SemanticNode *parent) {
	SemanticNodeBlockCreate *snbg = new SemanticNodeBlockCreate(createNodeParent, parent);
	const SyntaxTreeNode *reqNode = createNodeParent->Nodes->GetData(1)->Nodes->GetData(0);
	if (snbg->hasAfter()) snbg->setAfterExpression(analyzeNodeExpression(reqNode->Nodes->GetData(3)->Nodes->GetData(1), parent));
	if (snbg->hasDeviation()) snbg->setDeviationExpression(analyzeNodeExpression(reqNode->Nodes->GetData(4)->Nodes->GetData(2)->Nodes->GetData(1), parent));
	if (snbg->hasEvery()) snbg->setEveryExpression(analyzeNodeExpression(reqNode->Nodes->GetData(4)->Nodes->GetData(1), parent));
	if (snbg->hasUpto()) snbg->setUptoExpression(analyzeNodeExpression(reqNode->Nodes->GetData(1)->Nodes->GetData(1), parent));
	if (snbg->hasTransactionList()) {
		const SyntaxTreeNode *transListNode = reqNode->Nodes->GetData(2)->Nodes->GetData(2);
		SyntaxTreeNode *name = transListNode->Nodes->GetData(0);
		SyntaxTreeNode *expression = transListNode->Nodes->GetData(2);
		snbg->addTransaction(flattenNamePeriodAdd(*name), analyzeNodeExpression(expression, parent));
		SyntaxTreeNode *nextListNode = transListNode->Nodes->GetData(3);
		for (int x = 0; x < nextListNode->Nodes->GetCount(); ++x) {
			name = nextListNode->Nodes->GetData(x)->Nodes->GetData(1);
			expression = nextListNode->Nodes->GetData(x)->Nodes->GetData(3);
		}
	}
	return snbg;
}
/**
 *  @fn	SemanticNodeBlockBlockSplit* OurSemanticAnalyzer::analyzeNodeBlockSplit(const SyntaxTreeNod
 *  	e *splitNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block split.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	splitNodeParent	If non-null, the split node parent.
 *  @param	parent			If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockSplit *OurSemanticAnalyzer::analyzeNodeBlockSplit(const SyntaxTreeNode *splitNodeParent, SemanticNode *parent) {
	SemanticNodeBlockSplit *snbs = new SemanticNodeBlockSplit(splitNodeParent, parent);
	const SyntaxTreeNode *theNode = splitNodeParent->Nodes->GetData(1)->Nodes->GetData(0);
	if (snbs->hasInto()) snbs->setIntoExpression(analyzeNodeExpression(theNode->Nodes->GetData(1)->Nodes->GetData(1), parent));
	return snbs;
}
/**
 *  @fn	SemanticNodeBlockGather* OurSemanticAnalyzer::analyzeNodeBlockGather(const SyntaxTreeNode *
 *  	gatherNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block gather.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	gatherNodeParent	If non-null, the gather node parent.
 *  @param	parent				If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockGather *OurSemanticAnalyzer::analyzeNodeBlockGather(const SyntaxTreeNode *gatherNodeParent, SemanticNode *parent) {
	SemanticNodeBlockGather *snbg = new SemanticNodeBlockGather(gatherNodeParent, parent);
	const SyntaxTreeNode *theNode = gatherNodeParent->Nodes->GetData(1)->Nodes->GetData(0);
	if (snbg->hasExpression()) snbg->setExpression(analyzeNodeExpression(theNode->Nodes->GetData(2), parent));
	return snbg;
}
/**
 *  @fn	SemanticNodeBlockExecute* OurSemanticAnalyzer::analyzeNodeBlockExecute(const SyntaxTreeNode
 *  	*executeNodeParent, SemanticNode *parent)
 *
 *  @brief	Analyze node block execute.
 *
 *  @author	Nikola Novak
 *  @date	6/24/2009
 *
 *  @param	executeNodeParent	If non-null, the execute node parent.
 *  @param	parent				If non-null, the parent.
 *
 *  @return	null if it fails, else.
 */
SemanticNodeBlockExecute *OurSemanticAnalyzer::analyzeNodeBlockExecute(const SyntaxTreeNode *executeNodeParent, SemanticNode *parent) {
	return new SemanticNodeBlockExecute(executeNodeParent, parent);
}
